home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_098 / backup / backup.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  397 lines

  1.  
  2. #include "dir.h"
  3. #include "backup.h"
  4.  
  5. extern char *strsave ();
  6. extern char *pop ();
  7. extern int push ();
  8. extern char *build_name ();
  9. extern int in_dir ();
  10. extern int out_of_date ();
  11. extern struct FileLock *CreateDir ();
  12.  
  13.  
  14. void *stack = NULL;
  15. char sprbuf[ 1024 ];
  16. struct DateStamp bdate;
  17. int first_time;
  18.  
  19.  
  20. main ( argc , argv )
  21. int argc;
  22. char **argv;
  23. {
  24.     FILE *fp;
  25. #define LINE_SIZE    100
  26.     char linebuf[ LINE_SIZE ];
  27.     char *p , *parm1 , *parm2;
  28.  
  29.  
  30.     first_time = FALSE;
  31.     argc--;
  32.     argv++;
  33.     while ( argc > 0  &&  argv[0][0] == '-' ) {
  34.         switch ( argv[0][1] ) {
  35.         case 'f' :
  36.             first_time = TRUE;
  37.             break;
  38.         default :
  39.             puts ( "Unknown option %s\n" , argv[0] );
  40.             exit ( 1 );
  41.         }
  42.         argc--;
  43.         argv++;
  44.     }
  45.     if ( argc == 2 ) {
  46.         backup ( argv[0] , argv[1] );
  47.     }
  48.     else if ( argc == 1 ) {
  49.  
  50.         /* read from DO_BACKUP file on destination drive. */
  51.         /* it should contain lines containing two parameters for the */
  52.         /* backup command (eg: h2:thai thai-backup:) */
  53.  
  54.         fp = fopen ( build_name ( argv[0] , DO_BACKUP ) , "r" );
  55.         if ( fp == NULL ) {
  56.             printf ( "usage: unable to find %s file on destination disk\n" ,
  57.                 DO_BACKUP );
  58.         }
  59.         else {
  60.             while ( fgets ( linebuf , LINE_SIZE , fp ) != NULL ) {
  61.                 p = linebuf;
  62.                 while ( isspace ( *p ) )
  63.                     p++;
  64.                 if ( *p == '\0' )
  65.                     continue;
  66.                 parm1 = p;
  67.                 while ( !isspace ( *p ) )
  68.                     p++;
  69.                 *p++ = '\0';
  70.                 while ( isspace ( *p ) )
  71.                     p++;
  72.                 if ( *p == '\0' )
  73.                     continue;
  74.                 parm2 = p;
  75.                 while ( !isspace ( *p ) )
  76.                     p++;
  77.                 *p++ = '\0';
  78.                 while ( isspace ( *p ) )
  79.                     p++;
  80.                 if ( *p != '\0' ) {
  81.                     printf ( "illegal syntax in %s file\n" , DO_BACKUP );
  82.                     break;
  83.                 }
  84.                 printf ( "\nbackup %s %s\n\n" , parm1 , parm2 );
  85.                 backup ( parm1 , parm2 );
  86.             }
  87.             fclose ( fp );
  88.         }
  89.     }
  90.     else {
  91.         printf ( "usage: backup from to\n" );
  92.         printf ( "or     backup todisk\n" );
  93.     }
  94. }
  95.  
  96.  
  97. backup ( from , to )
  98. char *from , *to;
  99. {
  100.     struct dir_st *dir , *todir;
  101.     char *path;
  102.     struct dir_st *p;
  103.     int isdir;
  104.     struct DPTR *dptr;
  105.     struct FileLock *lock;
  106.     FILE *fp;
  107.     struct FileInfoBlock *fib;
  108.     int checkdir;
  109.  
  110.  
  111.     lock = Lock ( build_name ( to , BACKUP_FILE_NAME ) , (LONG)ACCESS_READ );
  112.     if ( lock == NULL ) {
  113.         if ( ! first_time ) {
  114.             puts ( ".backup not found: use -f for first time backup" );
  115.             exit ( 1 );
  116.         }
  117.         bdate.ds_Days = 0;
  118.         bdate.ds_Minute = 0;
  119.         bdate.ds_Tick = 0;
  120.     }
  121.     else {
  122.         fib = (struct FileInfoBlock *)
  123.             AllocMem ( (LONG) sizeof ( struct FileInfoBlock ) ,
  124.             (LONG) MEMF_PUBLIC );
  125.         if ( fib != NULL  &&  Examine ( lock , fib ) )
  126.             bdate = fib->fib_Date;
  127.         else {
  128.             bdate.ds_Days = 0;
  129.             bdate.ds_Minute = 0;
  130.             bdate.ds_Tick = 0;
  131.         }
  132.         if ( fib != NULL )
  133.             FreeMem ( fib , (LONG) sizeof ( struct FileInfoBlock ) );
  134.         UnLock ( lock );
  135.     }
  136.  
  137.     fp = fopen ( build_name ( to , BACKUP_FILE_NAME ) , "w" );
  138.     if ( fp == NULL ) {
  139.         puts ( "Failed to create .backup file for time stamp" );
  140.         return ( 0 );
  141.     }
  142.     fclose ( fp );
  143.  
  144.     if ( ! push ( &stack , "" ) ) {
  145.         puts ( "Aborting" );
  146.         return ( 0 );
  147.     }
  148.     while ( path = pop ( &stack ) ) {
  149.  
  150.         printf ( "Searching %s\n" , build_name ( from , path ) );
  151.         dir = getdir ( build_name ( from , path ) );
  152.         if ( dir == NULL ) {
  153.             puts ( "Aborting" );
  154.             return ( 0 );
  155.         }
  156.  
  157.         /* if original directory changed since last backup, a file */
  158.         /* may have been deleted. If this is so, must do dir on dest too */
  159.  
  160.         checkdir = FALSE;
  161.         dptr = dopen ( build_name ( from , path ) , &isdir );
  162.         if ( dptr == NULL  ||  ! isdir ) {
  163.             puts ( "Internal error!!!" );
  164.             freedir ( dir );
  165.             return ( 0 );
  166.         }
  167.         if ( out_of_date ( &dptr->fib->fib_Date ) )
  168.             checkdir = TRUE;
  169.         dclose ( dptr );
  170.  
  171.         /* ok, must also check destination disk in case files there */
  172.         /* have been added */
  173.  
  174.         dptr = dopen ( build_name ( to , path ) , &isdir );
  175.         if ( dptr == NULL  ||  ! isdir ) {
  176.  
  177.             if ( dptr != NULL  &&  ! isdir ) {
  178.                 /* Found a file where we want a directory */
  179.                 rm_file ( to , "" , path , isdir );
  180.             }
  181.  
  182.             printf ( "Creating  %s\n" ,
  183.                 build_name ( to , path ) );
  184.             lock = CreateDir ( build_name ( to , path ) );
  185.             if ( lock == NULL ) {
  186.                 printf ( "Failed to create %s\n" ,
  187.                     build_name ( to , path ) );
  188.                 freedir ( dir );
  189.                 dclose ( dptr );
  190.                 return ( 0 );
  191.             }
  192.             UnLock ( lock );
  193.         }
  194.         else {
  195.  
  196.             /* now, check date on destination directory. if changed, then */
  197.             /* files may have been created (which will have to be deleted) */
  198.  
  199.             if ( out_of_date ( &dptr->fib->fib_Date ) )
  200.                 checkdir = TRUE;
  201.         }
  202.         dclose ( dptr );
  203.  
  204.         if ( checkdir ) {
  205.  
  206.             /* Have to check if files have been deleted. */
  207.             /* To do this, must do a dir on destination drive. */
  208.  
  209.             printf ( "Searching %s\n" , build_name ( to , path ) );
  210.             todir = getdir ( build_name ( to , path ) );
  211.             if ( todir == NULL ) {
  212.                 puts ( "Aborting" );
  213.                 freedir ( dir );
  214.                 return ( 0 );
  215.             }
  216.  
  217.             for ( p = todir->next; p != NULL; p = p->next ) {
  218.                 if ( ! in_dir ( p->filename , dir ) )
  219.                     rm_file ( to , path , p->filename , p->dir );
  220.             }
  221.             freedir ( todir );
  222.         }
  223.  
  224.         for ( p = dir->next; p != NULL; p = p->next ) {
  225.             if ( p->dir ) {
  226.                 if ( ! push ( &stack , build_name ( path , p->filename ) ) ) {
  227.                     freedir ( dir );
  228.                     puts ( "Aborting" );
  229.                     return ( 0 );
  230.                 }
  231.             }
  232.             else {
  233.                 if ( out_of_date ( &p->date ) )
  234.                     copy_file ( from , to , path , p->filename );
  235.             }
  236.         }
  237.     }
  238.     return ( 1 );
  239. }
  240.  
  241.  
  242.  
  243. #define BSIZE    10000
  244.  
  245. copy_file ( from , to , path , filename )
  246. char *from , *to , *path , *filename;
  247. {
  248.     FILE *fromfp , *tofp;
  249.     static char buf[ BSIZE ];
  250.     int bytes;
  251.  
  252.     if ( path == NULL  ||  path[0] == '\0' )
  253.         strcpy ( sprbuf , filename );
  254.     else
  255.         sprintf ( sprbuf , "%s/%s" , path , filename );
  256.  
  257.     fromfp = fopen ( build_name ( from , sprbuf ) , "r" );
  258.     if ( fromfp == NULL ) {
  259.         printf ( "Failed to open '%s' for copying\n" ,
  260.             build_name ( from , sprbuf ) );
  261.         return;
  262.     }
  263.     tofp = fopen ( build_name ( to , sprbuf ) , "w" );
  264.     if ( tofp == NULL ) {
  265.         fclose ( fromfp );
  266.         printf ( "Failed to create '%s' to copy to\n" ,
  267.             build_name ( to , sprbuf ) );
  268.         return;
  269.     }
  270.     printf ( "Copying   %s ... " , sprbuf );
  271.     fflush ( stdout );
  272.     while ( ( bytes = fread ( buf , 1 , BSIZE , fromfp ) ) > 0 ) {
  273.         if ( fwrite ( buf , 1 , bytes , tofp ) != bytes ) {
  274.             printf ( "write error, " );
  275.             break;
  276.         }
  277.     }
  278.     fclose ( tofp );
  279.     fclose ( fromfp );
  280.     puts ( "done" );
  281. }
  282.  
  283.  
  284. rm_file ( root , path , filename , isdir )
  285. char *root;
  286. char *path;
  287. char *filename;
  288. int isdir;
  289. {
  290.     struct dir_st *p , *dir;
  291.     char *buf;
  292.  
  293.  
  294.     if ( path == NULL  ||  path[0] == '\0' ) {
  295.         strcpy ( sprbuf , filename );
  296.         buf = strsave ( sprbuf );
  297.     }
  298.     else {
  299.         sprintf ( sprbuf , "%s/%s" , path , filename );
  300.         buf = strsave ( sprbuf );
  301.     }
  302.     if ( strcmp ( buf , BACKUP_FILE_NAME ) == 0 )
  303.         return;
  304.     if ( buf == NULL ) {
  305.         puts ( "Out of memory!\n" );
  306.         return;
  307.     }
  308.     printf ( "Deleting %s %s\n" ,
  309.         isdir ? "directory" : "file" ,
  310.         build_name ( root , buf ) );
  311.     if ( isdir ) {
  312.         printf ( "Searching %s\n" , build_name ( root , buf ) );
  313.         dir = getdir ( build_name ( root , buf ) );
  314.         if ( dir == NULL ) {
  315.             printf ( "Failed to open directory %s\n" ,
  316.                 build_name ( root , buf ) );
  317.         }
  318.         else {
  319.             for ( p = dir->next; p != NULL; p = p->next )
  320.                 rm_file ( root , build_name ( path , filename ) ,
  321.                     p->filename , p->dir );
  322.             freedir ( dir );
  323.             /* Delete the directory */
  324.             DeleteFile ( build_name ( root , buf ) );
  325.         }
  326.     }
  327.     else
  328.         DeleteFile ( build_name ( root , buf ) );
  329.     free ( buf );
  330. }
  331.  
  332.  
  333. int
  334. in_dir ( filename , dir )
  335. char *filename;
  336. struct dir_st *dir;
  337. {
  338.     struct dir_st *p;
  339.  
  340.     for ( p = dir->next; p != NULL; p = p->next )
  341.         if ( strcmp ( p->filename , filename ) == 0 )
  342.             return ( 1 );
  343.     return ( 0 );
  344. }
  345.  
  346.  
  347. char *
  348. build_name ( root , filename )
  349. char *root , *filename;
  350. {
  351.     static char buf[ 512 ];
  352.  
  353.     strcpy ( buf , root );
  354.     if ( buf[0] != '\0'  &&  buf[ strlen ( buf ) - 1 ] != ':' )
  355.         strcat ( buf , "/" );
  356.     strcat ( buf , filename );
  357.     return ( buf );
  358. }
  359.  
  360.  
  361. char *
  362. strsave ( s )
  363. char *s;
  364. {
  365.     char *p;
  366.  
  367.     p = malloc ( strlen ( s ) + 1 );
  368.     if ( p != NULL )
  369.         strcpy ( p , s );
  370.     return ( p );
  371. }
  372.  
  373.  
  374. int
  375. out_of_date ( date )
  376. struct DateStamp *date;
  377. {
  378.     if ( date->ds_Days < bdate.ds_Days )
  379.         return ( 0 );
  380.     if ( date->ds_Days > bdate.ds_Days )
  381.         return ( 1 );
  382.     if ( date->ds_Minute < bdate.ds_Minute )
  383.         return ( 0 );
  384.     if ( date->ds_Minute > bdate.ds_Minute )
  385.         return ( 1 );
  386.     if ( date->ds_Tick < bdate.ds_Tick )
  387.         return ( 0 );
  388.     if ( date->ds_Tick > bdate.ds_Tick )
  389.         return ( 1 );
  390.     return ( 1 );
  391. }
  392.  
  393.  
  394. /* Aztec C playing up! Used by perror() */
  395. int sys_nerr = -1;
  396. char *sys_errlist[1];
  397.